﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Reflection;
using System.IO;
using GameEngine;
using Daphne.Presenters;

using ComputerEngine;
using Daphne.Forms;
using Tomers.WPF.Localization;

namespace Daphne
{
    /// <summary>
    /// Command handing
    /// </summary>
	public partial class MainWindow
	{
        private eGameType _savedGameType;

        private void CanExecuteRotateBoard(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _eBoardType == eBoardType.e2D;
            e.Handled = true;
        }
        private void ExecuteRotateBoard(object sender, ExecutedRoutedEventArgs e)
        {
            _presenter.Rotated = !_presenter.Rotated;
            uxBoard2D.InvalidateVisual();
        }

        private void CanExecutePersonView(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _eBoardType == eBoardType.e3D;
            e.Handled = true;
        }

        private void ExecutePersonView(object sender, ExecutedRoutedEventArgs e)
        {
            SetPersonView();
            e.Handled = true;
        }

        private void CanExecuteTopView(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _eBoardType == eBoardType.e3D;
            e.Handled = true;
        }

        private void ExecuteTopView(object sender, ExecutedRoutedEventArgs e)
        {
            Set3DView(Board3D.eBoardView.FromTop);
            e.Handled = true;
        }

        private void CanExecuteClearBoard(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _presenter == null ? false : _presenter.IsInEditMode();
            e.Handled = true;
        }
        private void ExecuteClearBoard(object sender, ExecutedRoutedEventArgs e)
        {
            _presenter.GameManager.GameBoard.CleanBoard();
            uxBoard2D.InvalidateVisual();
            e.Handled = true;
        }

        private void CanExecuteEditMode(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _eBoardType == eBoardType.e2D;
            e.Handled = true;
        }
        private void ExecuteEditMode(object sender, ExecutedRoutedEventArgs e)
        {
            _presenter.ToggleEditMode();
            if (_presenter.IsInEditMode() == true)
            {
                if (MessageBox.Show(GetTextValue("APP_ClearBoard"), GetTextValue("APP_PositionEditor"), MessageBoxButton.YesNo, MessageBoxImage.Question)
                    == MessageBoxResult.Yes)
                {
                    _mng.GameBoard.CleanBoard();
                }
            }
            else
            {
                _mng.GameBoard.SetOnMove(SelectOnMove());
            }

            _mng.MoveHistory.ClearMoves();
            this.GameUpdate();
            uxBoard2D.InvalidateVisual();
            e.Handled = true;
        }

        private enumFigureColor SelectOnMove()
        {
            Daphne.Forms.SelectOnMove frm = new Forms.SelectOnMove();
            frm.Owner = this;
            frm.ShowDialog();
            return frm.OnMove;
        }

        private void CanExecuteAbout(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
            e.Handled = true;
        }
        private void ExecuteAbout(object sender, ExecutedRoutedEventArgs e)
        {
            Daphne.Forms.AboutBox frm = new Forms.AboutBox();
            frm.Owner = this;
            frm.ShowDialog();
            e.Handled = true;
        }

        private void ExecuteMoveStart(object sender, ExecutedRoutedEventArgs e)
        {
            _presenter.GameManager.MoveHistory.MoveToBeginning();
            this.GameUpdate();
            uxBoard2D.InvalidateVisual();
            e.Handled = true;
        }
        private void CanExecuteMoveBack(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _presenter == null ? false : _presenter.GameManager.MoveHistory.CanMoveBack();
            e.Handled = true;
        }
        private void ExecuteMoveBack(object sender, ExecutedRoutedEventArgs e)
        {
            _presenter.GameManager.MoveHistory.MoveBack();
            uxBoard2D.InvalidateVisual();
            this.GameUpdate();
            e.Handled = true;
        }
        private void CanExecuteMoveForward(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _presenter == null ? false : _presenter.GameManager.MoveHistory.CanMoveForward();
            e.Handled = true;
        }
        private void ExecuteMoveForward(object sender, ExecutedRoutedEventArgs e)
        {
            _presenter.GameManager.MoveHistory.MoveForward();
            uxBoard2D.InvalidateVisual();
            this.GameUpdate();
            e.Handled = true;
        }
        private void ExecuteMoveEnd(object sender, ExecutedRoutedEventArgs e)
        {
            _presenter.GameManager.MoveHistory.MoveToEnd();
            uxBoard2D.InvalidateVisual();
            this.GameUpdate();
            e.Handled = true;
        }

        private void CanExecuteEngineMatch(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _presenter == null ? false : _presenter.IsInEditMode() == false;
            e.Handled = true;
        }

        private void ExecuteEngineMatch(object sender, ExecutedRoutedEventArgs e)
        {
            if (_GameType == eGameType.EngineMatch)
            {
                StopEngineMatch();
                SwitchGameType(_savedGameType);
            }
            else
            {
                _savedGameType = _GameType;
                SwitchGameType(eGameType.EngineMatch);
                StartEngineMatch();
            }
        }

        private void CanExecuteToggleComputerGame(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _GameType != eGameType.EngineMatch && (_presenter == null ? false : ! _presenter.IsInEditMode());
            e.Handled = true;
        }

        private void ExecuteToggleComputerGame(object sender, ExecutedRoutedEventArgs e)
        {
            if (_GameType == eGameType.OnePlayer)
            {
                SwitchGameType(eGameType.TwoPlayer);
                MessageBox.Show(GetTextValue("APP_TwoPlayerGame"));
            }
            else
            {
                SwitchGameType(eGameType.OnePlayer);
                MessageBox.Show(GetTextValue("APP_OnePlayerGame"));
            }

            e.Handled = true;
        }

        private void CanExecuteToggleBoardType(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _presenter == null ? false : _presenter.IsInEditMode() == false;
            e.Handled = true;
        }

        private void ExecuteToggleBoardType(object sender, ExecutedRoutedEventArgs e)
        {
            if (_eBoardType == eBoardType.e2D)
            {
                SwitchBoard(eBoardType.e3D);
            }
            else
            {
                SwitchBoard(eBoardType.e2D);
            }
            e.Handled = true;
        }

        private void CanExecuteExitApplication(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
            e.Handled = true;
        }

        private void ExecuteExitApplication(object sender, ExecutedRoutedEventArgs e)
        {
            this.Close();
            e.Handled = true;
        }

        private void CanExecuteNewGame(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _presenter == null ? false : _presenter.IsInEditMode() == false;
            e.Handled = true;
        }

        private void ExecuteNewGame(object sender, ExecutedRoutedEventArgs e)
        {
            NewGameForm frm = new NewGameForm();
            frm.Owner = this;
            if (frm.ShowDialog() == true)
            {
                StartNewGame(frm.NewGameSettings);
            }

            e.Handled = true;
        }

        private void CanExecuteLoadGame(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _presenter == null ? false : _presenter.IsInEditMode() == false;
            e.Handled = true;
        }

        private void ExecuteLoadGame(object sender, ExecutedRoutedEventArgs e)
        {
            LoadGame();
            e.Handled = true;
        }

        private void CanExecuteSaveGame(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _presenter == null ? false : _presenter.IsInEditMode() == false;
            e.Handled = true;
        }

        private void ExecuteSaveGame(object sender, ExecutedRoutedEventArgs e)
        {
            SaveGame();
            e.Handled = true;
        }

        private void CanExecuteComputerAdvice(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _mng != null &&_mng.EvaluateGameResult() == enumGameResult.Unknown
                && (_presenter == null ? false : _presenter.IsInEditMode() == false);
            e.Handled = true;
        }

        private void ExecuteComputerAdvice(object sender, ExecutedRoutedEventArgs e)
        {
            DoComputerAdvice();
            e.Handled = true;
        }

        private void CanExecuteLicenses(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
            e.Handled = true;
        }

        private void ExecuteLicenses(object sender, ExecutedRoutedEventArgs e)
        {
            Licenses form = new Licenses();
            form.Owner = this;
            form.Load(_sAppPath);
            form.ShowDialog();
            e.Handled = true;
        }

        private void CanExecuteComputerLevel(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
            e.Handled = true;
        }

        private void ExecuteComputerLevel(object sender, ExecutedRoutedEventArgs e)
        {
            int computerLevel;
            if (int.TryParse(e.Parameter.ToString(), out computerLevel) == true)
            {
                _iEngineLevel = computerLevel;
                uxGameStatus.UpdateComputerLevel(_iEngineLevel);

                _daphneConfig.ComputerLevel = _iEngineLevel;
                Config.Set<DaphneConfig>(_sDaphneConfigKey, _daphneConfig);

            }
        }

        private void CanExecuteGraphicsLevel(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
            e.Handled = true;
        }

        private void ExecuteGraphicsLevel(object sender, ExecutedRoutedEventArgs e)
        {
            int graphicsLevel;
            if (int.TryParse(e.Parameter.ToString(), out graphicsLevel) == true)
            {
                SetGraphicsLevel(graphicsLevel);
            }
        }

        private void CanExecuteRecentFileOpen(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = _presenter == null ? false : _presenter.IsInEditMode() == false;
            e.Handled = true;
        }

        private void ExecuteRecentFileOpen(object sender, ExecutedRoutedEventArgs e)
        {
            uxRibbonAppMenu.IsDropDownOpen = false;
            LoadPDNFile(e.Parameter as string);
            e.Handled = true;           
        }

        private void CanExecuteSetTheme(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
            e.Handled = true;
        }

        private void ExecuteSetTheme(object sender, ExecutedRoutedEventArgs e)
        {
            switch (Convert.ToInt32(e.Parameter))
            {
                case Theme.Classic:
                    SetTheme(enumTheme.Classic);
                    break;
                case Theme.BlackAndWhite:
                    SetTheme(enumTheme.BlackAndWhite);
                    break;
                case Theme.Marble:
                    SetTheme(enumTheme.Marble);
                    break;
            }

            e.Handled = true;
        }

        private void CanExecuteSetLanguage(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
            e.Handled = true;
        }

        private void ExecuteSetLanguage(object sender, ExecutedRoutedEventArgs e)
        {
            AskForLanguage(true);
            e.Handled = true;
        }

        private static string GetTextValue(string sKey)
        {
            const string keyValue = "Value";
            return LanguageContext.Instance.Dictionary.Translate<string>(sKey, keyValue);

        }
	}
}
